package com.scofd.signature;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.*;

public class Main {

    private static void testServerSignature(SignatureJNI signatureJNI) {
        String srcFilePath = "D:\\gy\\ofd\\files\\hello1.ofd";
        String destFilePath = "D:\\gy\\ofd\\files\\hello1_sign.ofd";
        ServerSignatureArgs serverSignatureArgs = new ServerSignatureArgs();
        serverSignatureArgs.setDocIndex(0);
        serverSignatureArgs.setPageNo(1);
        serverSignatureArgs.setSealX(100);
        serverSignatureArgs.setSealY(100);
        //serverSignatureArgs.setSignIndex(0);
        serverSignatureArgs.setSignId("b304dc88ff8a45e4adea351b0cad13");
        //serverSignatureArgs.setSealUserName("051@山东政采企业测试一@N913700000000000001@1");
        //serverSignatureArgs.setSealPassword("123456");
        serverSignatureArgs.setSessionId("cfd36ff06e3049b5a0972a5c5adb1d10");

//        boolean ret = signatureJNI.signByPage(srcFilePath, destFilePath, "", serverSignatureArgs);
//        System.out.println("signByPage result: " + ret);

        List<String> srcFilePathList = new ArrayList<>();
        srcFilePathList.add(srcFilePath);
        srcFilePathList.add("D:\\gy\\ofd\\files\\4.ofd");
        List<String> destFilePathList = new ArrayList<>();
        destFilePathList.add(destFilePath);
        destFilePathList.add("D:\\gy\\ofd\\files\\4_sign.ofd");
        boolean ret = signatureJNI.batchSignByPage(srcFilePathList, destFilePathList, null, serverSignatureArgs);
        System.out.println("signByPage result: " + ret);
    }

    public static void main(String[] args) throws IOException {
        System.out.println(System.getProperty("java.library.path"));

        Properties p = new Properties();

        try {
            p.load(Main.class.getResourceAsStream("signature.properties"));
        } catch (IOException var2) {
            return;
        }

        String licence = p.getProperty("licence", "");
        String oesDllFilePath = p.getProperty("oesDllFilePath", "");
        String ofdFilePath = p.getProperty("ofdFilePath", "");
        int docIndex = Integer.parseInt(p.getProperty("docIndex", ""));
        int pageIndex = Integer.parseInt(p.getProperty("pageIndex", ""));
        int pageId = Integer.parseInt(p.getProperty("pageId", ""));
        double sealX = Double.parseDouble(p.getProperty("sealX", ""));
        double sealY = Double.parseDouble(p.getProperty("sealY", ""));
        boolean isCrossPageSeal = Boolean.parseBoolean(p.getProperty("isCrossPageSeal", ""));

        System.load("D:\\gy\\c++\\projects\\yhseal\\bin64\\vc14\\Release\\libcrypto-1_1-x64.dll");
        System.load("D:\\gy\\c++\\projects\\yhseal\\bin64\\vc14\\Release\\libssl-1_1-x64.dll");
        System.load("D:\\gy\\c++\\projects\\yhseal\\bin64\\vc14\\Release\\libcurl.dll");
        System.load("D:\\gy\\c++\\projects\\yhseal\\bin64\\vc14\\Release\\log4cxx.dll");

        System.load("D:\\gy\\c++\\thirdparty_libs\\pdfium\\pdfium-112.0.5579.0-win-x64\\bin\\zlib.dll");
        System.load("D:\\gy\\c++\\thirdparty_libs\\pdfium\\pdfium-112.0.5579.0-win-x64\\bin\\libc++.dll");
        System.load("D:\\gy\\c++\\thirdparty_libs\\pdfium\\pdfium-112.0.5579.0-win-x64\\bin\\absl.dll");
        System.load("D:\\gy\\c++\\thirdparty_libs\\pdfium\\pdfium-112.0.5579.0-win-x64\\bin\\icuuc.dll");
        System.load("D:\\gy\\c++\\thirdparty_libs\\pdfium\\pdfium-112.0.5579.0-win-x64\\bin\\partition_alloc.dll");
        System.load("D:\\gy\\c++\\thirdparty_libs\\pdfium\\pdfium-112.0.5579.0-win-x64\\bin\\libpng.dll");
        System.load("D:\\gy\\c++\\thirdparty_libs\\pdfium\\pdfium-112.0.5579.0-win-x64\\bin\\pdfium.dll");
        System.load("D:\\gy\\c++\\projects\\screader3\\libs\\libyhpdf\\prebuilt\\win32\\vc14\\64-bit\\Release\\MT\\libyhpdf.dll");
        System.load("D:\\gy\\c++\\projects\\screader3\\libs\\podofo\\prebuilt\\win32\\vc14\\64-bit\\Release\\MT\\podofo.dll");

//        System.loadLibrary("libcrypto-1_1-x64");
//        System.loadLibrary("pdfium");
//        System.loadLibrary("libyhpdf");
//        System.loadLibrary("podofo");

//        System.load("D:\\Program Files (x86)\\gomain\\gomain\\libeay32.dll");
//        System.load("D:\\Program Files (x86)\\gomain\\gomain\\ssleay32.dll");
//        System.load("D:\\Program Files (x86)\\gomain\\gomain\\libcurl.dll");
//        System.load("D:\\Program Files (x86)\\gomain\\gomain\\PopPIN.dll");

        System.loadLibrary("yh_qtsignature");
        SignatureJNI signatureJNI = new SignatureJNI();

        // 获取机器码.
//        String machineCode = signatureJNI.getMachineCode();
//        if (machineCode != null) {
//            System.out.println("machineCode: " + machineCode);
//        }

        // 初始化.
        if (!signatureJNI.initialize(licence)) {
            System.err.println("signature initialize error");
            return;
        }

        // 注册OES组件.
        OESProviderInfo oesProviderInfo = new OESProviderInfo();
        if (!signatureJNI.registerOES(oesDllFilePath, oesProviderInfo)) {
            System.err.println("register oes error");
            return;
        }
        System.out.println(oesProviderInfo.toString());

        testServerSignature(signatureJNI);

//        boolean ret = signatureJNI.verifySignature("/root/pdf/1_sign.pdf", "", "");
//        System.out.println("ret: " + ret);

        // 不用调用.
//        boolean loginRet = signatureJNI.login(oesDllFilePath, "5DEA9117CCB84117BC6CE959CCEB8257");

//        byte[] certData = signatureJNI.getCertData(oesDllFilePath, "C64720A7A145499584B98B5535EE7225");
//        if (certData == null) {
//            return;
//        }

        // 卸载OES组件.
//        if (!signatureJNI.unregisterOES(oesDllFilePath)) {
//            System.err.println("unregister oes error");
//            return;
//        }

        // 获取印章列表.
        List<SealInfo> sealList = signatureJNI.getSealList(oesDllFilePath, "cfd36ff06e3049b5a0972a5c5adb1d10", "");
        if (sealList == null || sealList.isEmpty()) {
            System.err.println("get seal list error");
            return;
        }
        // 取第一个章.
        String sealId = sealList.get(0).puchSealId;

//        List<String> stringList = signatureJNI.delSealByName("D:\\gy\\pdf\\files\\3a67331515a1459f94b9c7293cc99e1e.pdf",
//                "D:\\1.pdf",
//                "YouHong Signature eba0e5643f454a17bdd9de93b57d8dbf6dfecacbe3d043618518f3f0cfdcfe16",
//                "MIIElDCCBDigAwIBAgIQaeIAAAG+va/1MD7ksQnOpzAMBggqgRzPVQGDdQUAMGIxCzAJBgNVBAYTAkNOMRIwEAYDVQQIDAnnpo/lu7rnnI" +
//                        "ExLTArBgNVBAoMJEZ1amlhbiBEaWdpdGFsIENlcnRpZmljYXRlIEF1dGhvcml0eTEQMA4GA1UEAwwHRkpDQVNNMjAeFw0yMzA3MTkxNjAwMDBaFw0yNDA3M" +
//                        "jAxNTU5NTlaMIG8MQswCQYDVQQGEwJDTjEPMA0GA1UECAwG56aP5bu6MQ8wDQYDVQQHDAbnpo/lt54xGzAZBgNVBAsMEjkxMzUwMTAyMDUyMzA3MTUxRDEkMCIG" +
//                        "A1UECwwb5q2k6K+B5Lmm5LuF5L2/55So5LqO5rWL6K+VMUgwRgYDVQQDDD/npo/lu7rnkZ7mnK/kv6Hmga/np5HmioDmnInpmZDlhazlj7jvvIjkuJrliqHkuJPnlK" +
//                        "jlhavljYHkuozvvIkwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAATnnD113eLR3vNKD0V5gEN+F7inj3b2PSRqAjAaMackj3X50W46/bxbEmc8pOAfkZR/mL3LDNkz/j" +
//                        "uP8p3dmum9o4ICcTCCAm0wDAYDVR0TBAUwAwEBADAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwCwYDVR0PBAQDAgDAMCIGByqBHIbvQgEEFzYwMTZAMTA5MkAwMDAwM" +
//                        "DA5OTcxMDgxMB4GCCqBHNAUBAEDBBI5MTM1MDEwMjA1MjMwNzE1MUQwHwYDVR0jBBgwFoAU07Iw7fyl6D46rmyjyk+8yA3jJnUwgdIGA1UdHwSByjCBxzCBxKCBwaCBvoaBjmxkY" +
//                        "XA6Ly8yMDIuMTA5LjE5NC4yMjk6Mzg5L0NOPUZKQ0FTTTIsQ049RkpDQVNNMiwgT1U9Q1JMRGlzdHJpYnV0ZVBvaW50cywgYz1jbj9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2J" +
//                        "hc2U/b2JqZWN0Y2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSGK2h0dHA6Ly8yMDIuMTA5LjE5NC4yMjkvZG93bmxvYWQvRkpDQVNNMi5jcmwwgdcGCCsGAQUFBwEBBIHKMIHHMIGLBg" +
//                        "grBgEFBQcwAoZ/bGRhcDovLzIwMi4xMDkuMTk0LjIyOTozODkvQ049RkpDQVNNMixDTj1GSkNBU00yLCBPVT1jQUNlcnRpZmljYXRlcywgYz1jbj9jQUNlcnRpZmljYXRlP2Jhc2U/b2Jq" +
//                        "ZWN0Q2xhc3M9Y2VydGlmaWNhdGlvbkF1dGhvcml0eTA3BggrBgEFBQcwAoYraHR0cDovLzIwMi4xMDkuMTk0LjIyOS9kb3dubG9hZC9GSkNBU00yLmNlcjAdBgNVHQ4EFgQUEKKp1BF71X" +
//                        "HkbpyNKPTpAB25bM8wDAYIKoEcz1UBg3UFAANIADBFAiAYukRkORlAuoZ0UmktNw0GUyoI1ydrolE7E9UyCRKJNQIhAKnCGvR6XQ1Ercq7o80WYh8C+p0BjDIVVODq/G66C1lt",
//                "");

//        String sealId = "";
//        String sealId = "xIJP=Ar4ScipBtQhT2NFy+DqM/s9Lbm6Ugd3YuaE1CKGovjwlnVz0WfO7HkeZ8RX5";
//        sealId = "YHSeal";
//        System.out.println("sealId: " + sealId);

//        String od = signatureJNI.getSignOriginalData(oesDllFilePath, ofdFilePath, "", "sm3", "");
//        System.out.println("od: " + od);

//        String digestStr = signatureJNI.digest("sm3", new String("test").getBytes(StandardCharsets.UTF_8));

//        SignatureArgs signatureArgs1 = new SignatureArgs();
//        signatureArgs1.setOfdFilePath(ofdFilePath);
//        //signatureArgs1.setTmpOutputPDFFilePath("D:\\1_sign2.pdf");
//        signatureArgs1.setDocIndex(docIndex);
//        signatureArgs1.setPageIndex(pageIndex);
//        //signatureArgs1.setPageIndexList(new int[]{0, 1, 2});
//        signatureArgs1.setSealId(sealId);
//        signatureArgs1.setSealX(sealX);
//        signatureArgs1.setSealY(sealY);
//
//        signatureArgs1.setSealWidth(40);
//        signatureArgs1.setSealHeight(40);
//        signatureArgs1.setSealImageType("jpg");
//        signatureArgs1.setSealImageBase64Data("123");
//        signatureArgs1.setDigestMethod("sm3");
//        signatureArgs1.setCertSignMsg("test");
//        signatureArgs1.setGetSignOriginalData(true);
//        String signatureTaskId2 = signatureJNI.signature("", signatureArgs1);
//        int signatureProgress11 = signatureJNI.getSignatureProgress(signatureTaskId2);
//        String errMsg1 = signatureJNI.getSignatureErrMsg(signatureTaskId2);
//        String signValuePath  = signatureJNI.getSignValuePath(signatureTaskId2);
//        List<OriginalData> signatureDataList1 = signatureJNI.getSignatureDataList(signatureTaskId2);
//        if (signatureDataList1 != null) {
//            for (OriginalData signatureData : signatureDataList1) {
//                System.out.println("signatureData fileLoc: " + signatureData.getFileLoc());
//                //if (signatureData.getFileLoc().contains("Signatures.xml"))
//                {
//                    System.out.println("signatureData fileData: " + new String(signatureData.getFileData()));
//                }
//            }
//        }
//        String signatureOriginalDataStr = signatureJNI.getSignatureOriginalData(signatureTaskId2);
//        System.out.println("signatureOriginalDataStr: " + signatureOriginalDataStr + ", errMsg1: " + errMsg1);

        // 签章(注意：同步方法).
        SignatureArgs signatureArgs = new SignatureArgs();
        //signatureArgs.setOesDllFilePath("D:\\gy\\c++\\projects\\yhseal\\bin64\\vc14\\Release\\yhoes.dll");
        // TODO: 指定参数.
        signatureArgs.setOfdFilePath(ofdFilePath);

//        signatureArgs.setTmpOutputPDFFilePath("D:\\1_sign.pdf");

//        byte[] srcOFDData = getFileByteArray(Paths.get(ofdFilePath).toFile());
//        signatureArgs.setOfdFileData(srcOFDData);

        signatureArgs.setDocIndex(docIndex);
        signatureArgs.setVerIndex(2);
        signatureArgs.setPageIndex(pageIndex);
//        signatureArgs.setPageId(pageId);
        // 印章ID从印章列表中获取.
        signatureArgs.setSealId(sealId);
        signatureArgs.setSealX(sealX);
        signatureArgs.setSealY(sealY);

        //signatureArgs.setOnlyDigitalSignature(true);

        // 关键字签章.
//        signatureArgs.setKeyWords("OFD");
//        signatureArgs.setPageIndexList(new int[]{0});
        //signatureArgs.setKeywordPosIndexList(new int[]{1, 2, 3});
//        signatureArgs.setKeywordPosIndexList(new int[]{-1, -2, -3});
//        signatureArgs.setDefaultInvalidKeywordPosIndex(1);

//        AdditionalTime additionalTime = new AdditionalTime();
//        additionalTime.setTimeStr("2023-7-27 10:47:46");
//        additionalTime.setTimeFontName("黑体");
//        additionalTime.setTimeColor("255 0 0");
//        signatureArgs.setAdditionalTime(additionalTime);

//        signatureArgs.setSealWidth(40);
//        signatureArgs.setSealHeight(40);
//        signatureArgs.setSealImageType("jpg");
//        signatureArgs.setSealImageBase64Data("123");
//        signatureArgs.setCertSignMsg(signatureOriginalDataStr);
//        signatureArgs.setDigestMethod("sm3");

//        signatureArgs.setCrossPageSeal(isCrossPageSeal);
//        signatureArgs.setBeginPageNo(1);
//        signatureArgs.setEndPageNo(14);
//        signatureArgs.setFirstPageRate(0.5f);
//        signatureArgs.setEqualDivision(3);
//        signatureArgs.setSealWidth(42);
//        signatureArgs.setSealHeight(42);

//        signatureArgs.setUseOriginalDataListAsDigestFileList(true);

        //signatureArgs.setCustomPuchDocProperty("{\"DocId\":\"e7c9a1d27901471cbc7a8ae8b37278ae\",\"DocName\":\"测试OFD\"}");

//        String signatureSignedInfoXML = signatureJNI.getSignatureSignedInfoXML(signatureArgs);

        List<OriginalData> originalDataList = new ArrayList<>();
        OriginalData originalData = new OriginalData();
        originalData.setFileLoc("Doc_0/test.xml");
        originalData.setFileData("test".getBytes(StandardCharsets.UTF_8));
        originalDataList.add(originalData);
//        signatureArgs.setOriginalDataList(originalDataList);
//        signatureArgs.setUseOriginalDataListAsDigestFileList(true);
        String signatureTaskId = signatureJNI.signature(oesDllFilePath, signatureArgs);
        if (signatureTaskId.isEmpty()) {
            // 获取签章错误信息.
            String errMsg = signatureJNI.getSignatureErrMsg(signatureTaskId);
            if (!errMsg.equals("")) {
                System.err.println("signature error: " + errMsg);
            }
            return;
        }

        List<SignaturePosArgs> signaturePosArgsList = signatureJNI.getSignaturePosInfoList(signatureTaskId);

        // 获取签章状态.
        int signatureStatus = signatureJNI.getSignatureStatus(signatureTaskId);
        System.out.println("signatureStatus: " + signatureStatus);

        // 获取签章进度.
        int signatureProgress = signatureJNI.getSignatureProgress(signatureTaskId);
        System.out.println("signatureProgress: " + signatureProgress);

        // 获取签章错误信息.
        String errMsg = signatureJNI.getSignatureErrMsg(signatureTaskId);
        if (!errMsg.equals("")) {
            System.err.println("signature error: " + errMsg);
        }

        // 保存签章OFD文件.
//        if (!signatureJNI.saveSignatureOFD(signatureTaskId)) {
//            System.err.println("save signature ofd error");
//            return;
//        }

        List<OriginalData> signatureDataList = signatureJNI.getSignatureDataList(signatureTaskId);
        if (signatureDataList != null) {
            for (OriginalData signatureData : signatureDataList) {
                System.out.println("signatureData fileLoc: " + signatureData.getFileLoc());
                if (signatureData.getFileLoc().contains("Signatures.xml")) {
                    System.out.println("signatureData fileData: " + new String(signatureData.getFileData()));
                }

                // Debug.
                originalData = new OriginalData();
                originalData.setFileLoc(signatureData.getFileLoc());
                originalData.setFileData(signatureData.getFileData());
                originalDataList.add(originalData);
                signatureArgs.setOriginalDataList(originalDataList);
            }
        }

        byte[] signatureOFDData = signatureJNI.getSignatureOFDData(signatureTaskId);
        if (signatureOFDData != null) {
            System.out.println("write finish");
            OutputStream resultOutStream = new FileOutputStream("./sign.ofd");
            resultOutStream.write(signatureOFDData);
            resultOutStream.close();
        }
        signatureJNI.destroySignatureTask(signatureTaskId);

        signatureArgs.setVerIndex(2);
        signatureArgs.setOfdFileData(signatureOFDData);
        String signatureTaskId1 = signatureJNI.signature(oesDllFilePath, signatureArgs);
        if (signatureTaskId1.isEmpty()) {
            return;
        }
        signatureStatus = signatureJNI.getSignatureStatus(signatureTaskId1);
        System.out.println("signatureStatus: " + signatureStatus);
        errMsg = signatureJNI.getSignatureErrMsg(signatureTaskId);
        if (!errMsg.equals("")) {
            System.err.println("signature error: " + errMsg);
        }
        signatureDataList = signatureJNI.getSignatureDataList(signatureTaskId1);
        if (signatureDataList != null) {
            for (OriginalData signatureData : signatureDataList) {
                System.out.println("signatureData fileLoc: " + signatureData.getFileLoc());
                if (signatureData.getFileLoc().contains("Signatures.xml")) {
                    System.out.println("signatureData fileData: " + new String(signatureData.getFileData()));
                }
            }
        }

        signatureOFDData = signatureJNI.getSignatureOFDData(signatureTaskId1);
        if (signatureOFDData != null) {
            System.out.println("write finish");
            OutputStream resultOutStream = new FileOutputStream("./sign.ofd");
            resultOutStream.write(signatureOFDData);
            resultOutStream.close();
        }

        // 销毁签章任务.
        signatureJNI.destroySignatureTask(signatureTaskId1);

        // 销毁.
        signatureJNI.finalize();
    }

    public static byte[] getFileByteArray(File file) {
        long fileSize = file.length();
        if (fileSize > Integer.MAX_VALUE) {
            System.out.println("file too big...");
            return null;
        }
        byte[] buffer = null;
        try (FileInputStream fi = new FileInputStream(file)) {
            buffer = new byte[(int) fileSize];
            int offset = 0;
            int numRead = 0;
            while (offset < buffer.length
                    && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
                offset += numRead;
            }
            // 确保所有数据均被读取
            if (offset != buffer.length) {
                throw new IOException("Could not completely read file "
                        + file.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buffer;
    }
}
